#!/usr/bin/python2.7
# -*- coding: cp1252 -*-
#
# Copyright 2012 Darkspace revelations ltd. All Rights Reserved.
# adapted from the Startrek and Spectrek BASIC versions of way back (1970' - 1980's)

"""

    Coopymissions.py
    
    Mission data and logic for CoopyTrek
    on Google App Engine

"""
from coopyentity import *

missions = [{
        "name" : "1.1",
        "title" : "That could not have been a Kling-on or could it?",
        "description" : """A transport ship had gone missing and was found destroyed and 
         stripped in the New Beta-5 zone. Speculations rise: this was not an attack by 
         extremists or raiders. The ship couldn't have fallen prey to a Kling-on fighter, 
         could it?""",
        "briefing" : """We received a distress signal of a transport ship on its way to 
         Starbase Romulus, however it stopped sending signals an hour ago. We have no  
         knowledge about raiders in the area and the distress message mentioned a Kling-on
         fighter""",
        "zoneSize" : (4,4),
        "zoneName" : "New Beta-5", 
        "playerSpawns" : [{
                        "quadrant" : (0,1),
                        "sector" : (3,3) 
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,5)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,7)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,9)}
                    ],
        "stages" : [{
                    "objectives" : [1],
                    "entities" : [{
                         "etype" : ENTITY_KLINGON,  
                         "quadrant" : (3,2), 
                         "sector" : (15,10), 
                         "kwargs" : {
                           "events" : {"OnScanned" : ["Objective2_complete","MezzoKlingon1_1"],
                                     "OnTarget" : ["Objective2_complete","MezzoKlingon1_1"]} 
                                    }
                        },{ 
                         "etype" : ENTITY_WRECK, 
                         "number" : 1, 
                         "quadrant" : (2,2), 
                         "sector" : (10,10), 
                         "kwargs" : {
                            "scanMessage" : "It looks like this ship was attacked by other weapons than ordinary raider missiles",
                            "events" : {"OnScanned" : ["Objective1_complete"]}
                                    }
                        },{ 
                         "etype" : ENTITY_STARBASE, 
                         "quadrant" : (0,1), 
                         "sector" : (12,8),
                         "kwargs" : {"name" : "Romulus" }
                        },{ 
                         "etype": ENTITY_PLANET, 
                         "quadrant" : (0,1), 
                         "sector" : (15,12),
                         "kwargs" : {
                            "name" : "B5-Armulia", 
                            "scanMessage" : "This planet is home to three small colonies of humans, with a total of 300.000 people",
                            "events" : {"OnScan" : ["MezzoPlanetArmulia"]}
                            }
                         
                        },{ 
                         "etype": ENTITY_STAR, 
                         "quadrant" : (0,1), 
                         "sector" : (18,13),
                         "kwargs" : {
                            "name" : "B5", 
                            "scanMessage" : "A large category Red star."
                            }
                        }
                      ] #entities
                    } # wave 1     
                  ], #stages
        "newmissions" : "0100000000",
        "score" : 2000
       }, #mission
       {
        "name" : "1.2",
        "title" : "Engage!",
        "description" : """That Kling-on fighter is still around and FREHS command thinks 
         it's opportune to find out where it came from. """,
        "briefing" : """That Kling-on fighter is still around and FREHS command thinks 
         it's opportune to find out where it came from. Either approach, stealthily 
         follow or destroy it. FREHS command has risen the amber alert state. Use of 
         Phaser systems is cleared and you must engage the Kling-on.""",
        "zoneSize" : (4,4),
        "zoneName" : "New Beta-5", 
        "playerSpawns" : [{
                        "quadrant" : (0,1),
                        "sector" : (3,3) 
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,5)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,7)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,9)}
                    ],
        "stages" : [{
                    "objectives" : [1,3],
                    "entities" : [{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (3,2), 
                        "sector" : (15,10), 
                        "kwargs" : {
                          "events" : {
                             "OnDestroy" : ["Objective1_strikeoff"]}
                                   },
                        "scriptMember" : "hoverTravel" 
                        },{ 
                         "etype" : ENTITY_STARBASE, 
                         "quadrant" : (0,1), 
                         "sector" : (12,8),
                         "kwargs" : {"name" : "Romulus" }
                        },{ 
                         "etype": ENTITY_PLANET, 
                         "quadrant" : (0,1), 
                         "sector" : (15,12),
                         "kwargs" : {
                            "name" : "B5-Armulia", 
                            "scanMessage" : "This planet is home to three small colonies of humans, with a total of 300.000 people",
                            "events" : {"OnScan" : "MezzoPlanetArmulia"}
                                    }
                        },{ 
                         "etype": ENTITY_SPAWNER, 
                         "quadrant" : (3,3), 
                         "sector" : (10,10),
                         "kwargs" : {
                            "active" : True,
                            "isglobal" : True,
                            "spawnCounter" : 5,
                            "spawnEtype" : ENTITY_KLINGON,
                            "spawnNumber" : 3,
                            "spawnRange" : 5,
                            "spawnKwargs" : {"events" : {"OnDestroy" : ["Objective2_strikeoff"]}}
                            }
                        },{ 
                         "etype": ENTITY_STAR, 
                         "quadrant" : (0,1), 
                         "sector" : (18,13),
                         "kwargs" : {
                            "name" : "B5", 
                            "scanMessage" : "A large category Red star."
                            }
                        }
                    ]      
                  }
                ],
        "newmissions" : "0010000000",
        "score" : 5000
        },
        {
        "name" : "1.3",
        "title" : "Kling-ons abound",
        "description" : """Still believing this must have been a happen-stance run-in, 
         FREHS command is determined to destroy all the arch-enemy's ships, before they 
         escape and inform their leaders.""",
        "briefing" : """The group of Kling-on fighters that ran into our undertakings in 
         the New Beta-5 zone have gathered and are moving in on our Starbases. We believe 
         none of them have warned their homefront, so we still have an opportunity to 
         snuff out trouble while the fire is so small.
        
         Commander, go out there and destroy our enemy's ships. Let no ship escape the 
         zone, they will warn their tribes and that would be disastrous.""",
        "zoneSize" : (4,4),
        "zoneName" : "New Beta-5", 
        "playerSpawns" : [{
                        "quadrant" : (0,1),
                        "sector" : (3,3) 
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,5)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,7)
                        },{
                         "quadrant" : (0,1),
                         "sector" : (3,9)}
                    ],
        "stages" : [{
                    "objectives" : [15],
                    "entities" : [{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (2,2), 
                        "sector" : (13,10), 
                        "multiply" : 5,
                        "range" : 5,
                        "kwargs" : {
                          "events" : {
                             "OnDestroy" : ["Objective1_strikeoff"]} 
                                   }
                        },{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (3,2), 
                        "sector" : (13,10), 
                        "multiply" : 5,
                        "range" : 5,
                        "kwargs" : {
                          "events" : {
                             "OnDestroy" : ["Objective1_strikeoff"]}
                                   } 
                        },{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (3,3), 
                        "sector" : (13,10), 
                        "kwargs" : {
                          "events" : {
                             "OnDestroy" : ["Objective1_strikeoff", "ActivateSpawner"]}
                                   } 
                        },{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (3,3), 
                        "sector" : (10,10), 
                        "kwargs" : {
                            "events" : {
                               "OnDestroy" : ["Objective1_strikeoff", "ActivateSpawner"]}
                            }
                        },{ 
                         "etype" : ENTITY_STARBASE, 
                         "quadrant" : (0,1), 
                         "sector" : (12,8),
                         "kwargs" : {"name" : "Romulus" }
                        },{ 
                         "etype": ENTITY_PLANET, 
                         "quadrant" : (0,1), 
                         "sector" : (15,12),
                         "kwargs" : {
                            "name" : "B5-Armulia", 
                            "scanMessage" : "This planet is home to three small colonies of humans, with a total of 300.000 people",
                            "events" : {"OnScan" : "MezzoPlanetArmulia"}
                            },
                        },{ 
                         "etype": ENTITY_SPAWNER, 
                         "quadrant" : (3,3), 
                         "sector" : (10,10),
                         "kwargs" : {
                            "active" : False,
                            "isglobal" : True,
                            "spawnEtype" : ENTITY_KLINGON,
                            "spawnNumber" : 3,
                            "spawnRange" : 5,
                            "spawnKwargs" : {"events" : {"OnDestroy" : ["Objective1_strikeoff"]}}
                            }
                        },{ 
                         "etype": ENTITY_STAR, 
                         "quadrant" : (0,1), 
                         "sector" : (18,13),
                         "kwargs" : {
                            "name" : "B5", 
                            "scanMessage" : "A large category Red star."
                            }
                        }
                    ]      
                  }
                ],
        "newmissions" : "0001000000",
        "score" : 7500
        },
        {
        "name" : "2.1",
        "title" : "Test",
        "description" : """Test mission""",
        "briefing" : """kill all klingons""",
        "newmissions" : "0000000000",
        "score" : 0,
        "zoneSize" : (1,1),
        "zoneName" : "Test", 
        "playerSpawns" : [{
                        "quadrant" : (0,0),
                        "sector" : (3,3) 
                        },{
                         "quadrant" : (0,0),
                         "sector" : (3,5)
                        },{
                         "quadrant" : (0,0),
                         "sector" : (3,7)
                        },{
                         "quadrant" : (0,0),
                         "sector" : (3,9)}
                    ],
        "stages" : [{
                    "objectives" : [2],
                    "entities" : [{
                        "etype" : ENTITY_KLINGON,  
                        "quadrant" : (0,0), 
                        "sector" : (13,10), 
                        "multiply" : 2,
                        "range" : 5,
                        "kwargs" : {
                          "events" : {
                             "OnDestroy" : ["Objective1_strikeoff"]} 
                                   }
                        }]
                    }]
        }]


def objectiveComplete (mission, objective, entity):
    """ set the objective to complete, broadcast and check if all objectives are
        completed
    """
    all_complete = 0
    try:
        mission.objectives[objective] = 0
        mission.game.broadcast("Mission "+str(mission.title)+" objective #"+str(objective)+" complete!")
    except:
        logging.error ('Error: mission '+str(mission.title)+' does not have this objective. ' + str(mission.objectives) + ',  '+ str (objective))
    for objectiveStatus in mission.objectives:
        all_complete += objectiveStatus
    if (all_complete==0):
        mission.stageComplete()
            
def mezzo (mission, mezzoname, entity):
    pass
    
def objectiveStrikeoff (mission, objective, entity):
    mission.objectives[objective] -= 1
    if (mission.objectives[objective] <= 0):
        objectiveComplete (mission, objective,entity)

def activateSpawner (mission, nothing, entity):
    pass
    
eventHandlers = {
    "Objective1_complete" : (objectiveComplete, 0),
    "Objective2_complete" : (objectiveComplete, 1),
    "MezzoKlingon1_1" : (mezzo, "Klingon1_1"),
    "MezzoPlanetArmulia" : (mezzo, "PlanetArmulia"),
    "Objective1_strikeoff" : (objectiveStrikeoff, 0),
    "Objective2_strikeoff" : (objectiveStrikeoff, 1),
    "ActivateSpawner" : (activateSpawner, "")   
    }

def availableMissions(missionlist):
    """ return mission-data on the missions mentioned in the missionslist (usually 
        from the user profile 
    """
    playermissions = []
    i=0
    l=len(missionlist)
    if (l>len(missions)):
        l=len(missions)
    while (i<l):
        n = missionlist[i]
        if (n>"0"):
            missionshort = {
                "number" : i,
                "name" : missions[i]["name"],
                "title" : missions[i]["title"], 
                "description" : missions[i]["description"],
                "briefing" : missions[i]["briefing"],
                "level" : n}
            playermissions.append(missionshort)
        i+=1
    return playermissions


class Mission ():
   
    def __init__(self, game, mission, stage=0, difficulty=0):
        """ load mission data from missionlist, stage the mission """
        self.mission = mission
        self.game = game
        self.title = missions[mission].get("title","Untitled mission")
        self.difficulty = difficulty
        (game.galaxy_mx, game.galaxy_my) = missions[mission].get("zoneSize",(8,8)) # default to (8,8)
        self.newmissions = missions[mission].get("newmissions","1000000000")
        self.startStage(stage)
        
    def startStage (self, stage=0):
        self.stage=stage
        stages = missions[self.mission].get("stages")
        if (len(stages)>1):
            self.game.broadcast("Starting stage "+str(stage+1))
        if (stages):
            if (len(stages)>stage):
                self.objectives = stages[stage].get("objectives",[1])
                entities = stages[stage].get("entities")
                if (entities):
                    for e in entities:
                        n = e.get("multiply",1)
                        for i in range(n):
                            self.game.add_entity(
                                entityCreator(e.get("etype"), self.game, **e.get("kwargs")),
                                e.get("quadrant",(0,0)),
                                e.get("sector",(10,10)),
                                e.get("range",0))
                else:
                    logging.warning("No entities in this stage...?")
            else: # No more stages = mission complete.
                self.missionComplete()
        else:
            logging.warning("Requested mission does not have stages defined")
            
    def stageComplete (self):
        self.game.broadcast("Stage "+str(self.stage)+" complete!")
        if (len(missions[self.mission].get("stages",0))>self.stage):
            self.startStage(self.stage+1)
        else:
        	self.missionComplete()
    
    def missionComplete (self):
        self.game.broadcast("Mission complete!")
        self.game.end_mission()
    
    def playerSpawn (self, preferred=0):
        defaultSpawn = {"quadrant" : (0,1), "sector" : (3,3)}
        pS = missions[self.mission].get("playerSpawns",[defaultSpawn])
        if (preferred<=len(pS)):
            return pS[preferred]
        else:
            return defaultSpawn
    
    def giveCommand (self, entity):
        pass
        
    def evaluate (self):
        pass
    
    def eventHandler (self, entity, event):
        if (event in eventHandlers.keys()):
            eventHandlers[event][0](self, eventHandlers[event][1], entity)
        else:
            logging.warning("No such event defined: "+event)
    
